package org.jeecg.modules.lab.items.item.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.cronJob.MyEnum;
import org.jeecg.common.cronJob.entity.LabCronJob;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.lab.cronJob.service.ILabCronJobService;
import org.jeecg.modules.lab.items.entity.LabItems;
import org.jeecg.modules.lab.items.entity.LabItemsDevice;
import org.jeecg.modules.lab.items.item.service.ILabItemsDeviceService;
import org.jeecg.modules.lab.items.item.service.ILabItemsService;
import org.jeecg.modules.lab.items.temp.entity.LabItemsTempNorm;
import org.jeecg.modules.lab.items.temp.entity.LabItemsTempPerson;
import org.jeecg.modules.lab.items.temp.entity.LabItemsTempSample;
import org.jeecg.modules.lab.items.temp.entity.LabItemsTempTarget;
import org.jeecg.modules.lab.items.temp.service.ILabItemsTempNormService;
import org.jeecg.modules.lab.items.temp.service.ILabItemsTempPersonService;
import org.jeecg.modules.lab.items.temp.service.ILabItemsTempSampleService;
import org.jeecg.modules.lab.items.temp.service.ILabItemsTempTargetService;
import org.jeecg.modules.lab.items.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @Description: 实验项目信息表
 * @Author: jeecg-boot
 * @Date: 2023-07-20
 * @Version: V1.0
 */
@Api(tags = "实验项目信息表")
@RestController
@RequestMapping("/items/labItems")
@Slf4j
public class LabItemsController extends JeecgController<LabItems, ILabItemsService> {
    @Autowired
    private ILabItemsService labItemsService;
    @Autowired
    private ILabCronJobService labCronJobService;
    @Autowired
    private ILabItemsTempSampleService labItemsTempSampleService;
    @Autowired
    private ILabItemsTempNormService labItemsTempNormService;
    @Autowired
    private ILabItemsTempTargetService labItemsTempTargetService;
    @Autowired
    private ILabItemsTempPersonService labItemsTempPersonService;
    @Autowired
    private ILabItemsDeviceService labItemsDeviceService;

    /**
     * 分页列表查询
     *
     * @param labItems
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @ApiOperation(value = "实验项目信息表-分页列表查询", notes = "实验项目信息表-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<LabItems>> queryPageList(LabItems labItems,
                                                 @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                 @RequestParam(name = "pageSize", defaultValue = "20") Integer pageSize,
                                                 HttpServletRequest req) {
        QueryWrapper<LabItems> queryWrapper = QueryGenerator.initQueryWrapper(labItems, req.getParameterMap());
        Page<LabItems> page = new Page<LabItems>(pageNo, pageSize);
        IPage<LabItems> pageList = labItemsService.page(page, queryWrapper);
        return Result.OK(pageList);
    }


    /**
     * 项目标准分页列表查询
     */
    @ApiOperation(value = "实验项目信息表-项目标准分页列表查询", notes = "实验项目信息表-项目标准分页列表查询")
    @GetMapping(value = "/basisItemslist")
    public Result<IPage<LabItemsBasisItemsPage>> queryBasisItemsList(@RequestParam(name = "sortId", defaultValue = "") String sortId,
                                                                     @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                                     @RequestParam(name = "pageSize", defaultValue = "20") Integer pageSize,
                                                                     HttpServletRequest req) {

        List<LabItemsBasisItemsPage> itemsList = labItemsService.getBasisItemsList(sortId);
        IPage<LabItemsBasisItemsPage> pageList = new Page<>(pageNo, pageSize);
        pageList.setRecords(itemsList);
        pageList.setTotal(itemsList.size());
        return Result.OK(pageList);
    }


    /**
     * 分类树形查询
     *
     * @return
     */
    @ApiOperation(value = "实验项目信息表-分类树形查询", notes = "实验项目信息表-分类树形查询")
    @GetMapping(value = "/itemsTreeList")
    public Result<List<LabItemsTreePage>> treeLis() {

        List<LabItemsTreePage> labItemsTreePages = new ArrayList<>();
        QueryWrapper<LabItems> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type", "A");
        queryWrapper.orderByAsc("create_time");
        List<LabItems> labItemsList = labItemsService.list(queryWrapper);
        for (LabItems items : labItemsList) {
            LabItemsTreePage labItemsTreePage = new LabItemsTreePage();
            labItemsTreePage.setId(items.getId());
            labItemsTreePage.setName(items.getName());
            queryWrapper.clear();
            queryWrapper.eq("type", "B");
            queryWrapper.eq("pid", items.getId());
            queryWrapper.orderByAsc("create_time");
            List<LabItems> labItemsListA = labItemsService.list(queryWrapper);
            labItemsTreePage.setLabItemsList(labItemsListA);
            labItemsTreePages.add(labItemsTreePage);
        }
        return Result.OK(labItemsTreePages);
    }

    /**
     * 根据父类pid查询
     *
     * @param
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping(value = "/queryByPid")
    public Result<IPage<LabItems>> queryByPid(String id,
                                              @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                              @RequestParam(name = "pageSize", defaultValue = "20") Integer pageSize) {
        QueryWrapper<LabItems> labItemsQueryWrapper = new QueryWrapper<>();
        labItemsQueryWrapper.eq("pid", id);
        Page<LabItems> labItemsPage = new Page<>(pageNo, pageSize);
        Page<LabItems> itemsPage = labItemsService.page(labItemsPage, labItemsQueryWrapper);
        return Result.ok(itemsPage);
    }

    /**
     * 根据父类pid查询（项目+标准）
     *
     * @param
     * @return
     */
    @GetMapping(value = "/queryItemsByPid")
    public Result<List<LabItemsPage>> queryItemsByPid(String id) {
        List<LabItemsPage> itemsPage = labItemsService.getListItemsByPid(id);
        return Result.ok(itemsPage);
    }


    /**
     * 项目-标准
     *
     * @param itemName
     * @param team
     * @param sortType
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping(value = "/getItemsBasisList")
    public Result<IPage<LabItemsBasisPage>> getItemsBasisList(@RequestParam(name = "itemName", defaultValue = "") String itemName,
                                                              @RequestParam(name = "team", defaultValue = "") String team,
                                                              @RequestParam(name = "sortType", defaultValue = "") String sortType,
                                                              @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                              @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        List<LabItemsBasisPage> labItemsBasisList = labItemsService.getItemsLits(itemName, team, sortType);
        Page<LabItemsBasisPage> labItemsPage = new Page<>(pageNo, pageSize);
        labItemsPage.setRecords(labItemsBasisList);
        return Result.ok(labItemsPage);
    }


    /**
     * 根据实验项目id查询模板
     *
     * @return
     */
    @ApiOperation(value = "实验项目-根据实验项目id查询模板数据", notes = "实验项目-根据实验项目id查询模板")
    @GetMapping(value = "/getItemsTempData")
    public Result<LabItemTempPage> getItemsTempData(@RequestParam(name = "itemId", required = true) String itemId) {
        LabItemTempPage labItemTempPage = new LabItemTempPage();
        labItemTempPage.setLabTempSamList(labItemsTempSampleService.handTempData(itemId));

        labItemTempPage.setLabTempNormList(labItemsTempNormService.handTempData(itemId));

        labItemTempPage.setLabTempTargList(labItemsTempTargetService.handTempData(itemId));

        labItemTempPage.setLabTempPerList(labItemsTempPersonService.handTempData(itemId));
        return Result.OK(labItemTempPage);
    }

//    /**
//     * 添加
//     *
//     * @param labItems
//     * @return
//     */
//    @AutoLog(value = "实验项目信息表-添加")
//    @ApiOperation(value = "实验项目信息表-添加", notes = "实验项目信息表-添加")
//    @PostMapping(value = "/add")
//    public Result<String> add(@RequestBody LabItems labItems) {
//        labItemsService.save(labItems);
//        if (MyEnum.sync) {
//            long time = new Date().getTime();
//            LabCronJob job = new LabCronJob("lab_items", "0", time, 1);
//            labCronJobService.save(job);
//        }
//        return Result.OK("添加成功！");
//    }


    /**
     * 添加
     *
     * @param labItemsDeviceVo
     * @return
     */
    @AutoLog(value = "实验项目信息表-添加")
    @ApiOperation(value = "实验项目信息表-添加", notes = "实验项目信息表-添加")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody LabItemsDeviceVo labItemsDeviceVo) {
        labItemsService.savaItems(labItemsDeviceVo);
        if (MyEnum.sync) {
            //同步表信息
            long time = new Date().getTime();
            List<LabCronJob> jobs = new ArrayList<>();
            jobs.add(new LabCronJob("lab_items", "0", time, 1));
            jobs.add(new LabCronJob("lab_items_device", "0", time, 2));
            labCronJobService.saveBatch(jobs);
        }
        return Result.OK("添加成功！");
    }

//    /**
//     * 编辑
//     *
//     * @param labItems
//     * @return
//     */
//    @AutoLog(value = "实验项目信息表-编辑")
//    @ApiOperation(value = "实验项目信息表-编辑", notes = "实验项目信息表-编辑")
//    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
//    public Result<String> edit(@RequestBody LabItems labItems) {
//        labItems.setSynFlag("1");
//        labItemsService.updateById(labItems);
//
//        if (MyEnum.sync) {
//            long time = new Date().getTime();
//            LabCronJob job = new LabCronJob("lab_items", "1", time, 1);
//            labCronJobService.save(job);
//        }
//        return Result.OK("编辑成功!");
//    }


    /**
     * 编辑
     *
     * @param labItemsDeviceVo
     * @return
     */
    @AutoLog(value = "实验项目信息表-编辑")
    @ApiOperation(value = "实验项目信息表-编辑", notes = "实验项目信息表-编辑")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> edit(@RequestBody LabItemsDeviceVo labItemsDeviceVo) {
        labItemsService.updateItems(labItemsDeviceVo);
        if (MyEnum.sync) {
            long time = new Date().getTime();
            List<LabCronJob> jobs = new ArrayList<>();
            jobs.add(new LabCronJob("lab_items", "1", time, 1));
            String condition = " item_id='" + labItemsDeviceVo.getId() + "'";
            jobs.add(new LabCronJob("lab_items_device", "2", condition, time, 2));
            jobs.add(new LabCronJob("lab_items_device", "0", time, 3));
            labCronJobService.saveBatch(jobs);
        }
        return Result.OK("编辑成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "实验项目信息表-通过id删除")
    @ApiOperation(value = "实验项目信息表-通过id删除", notes = "实验项目信息表-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
        LabItems labItems = labItemsService.getById(id);
        String type = labItems.getType();
        List<String> itemIds = new ArrayList<>();
        List<String> devIds = new ArrayList<>();
        if (type.equals("A")) {
            List<String> idsA = new ArrayList<>();
            QueryWrapper<LabItems> queryWrapperA = new QueryWrapper<>();
            queryWrapperA.eq("pid", labItems.getId());
            List<LabItems> itemsListA = labItemsService.list(queryWrapperA);
            if (itemsListA != null) {
                for (LabItems item : itemsListA) {
                    idsA.add(item.getId());
                    itemIds.add(item.getId());
                }
            }
            if (idsA.size() > 0) {
                List<String> idsB = new ArrayList<>();
                QueryWrapper<LabItems> queryWrapperB = new QueryWrapper<>();
                queryWrapperB.in("pid", idsA);
                List<LabItems> itemsListB = labItemsService.list(queryWrapperB);
                if (itemsListB != null) {
                    for (LabItems item : itemsListB) {
                        idsB.add(item.getId());
                        itemIds.add(item.getId());
                    }
                }
                if (idsB.size() > 0) {
                    QueryWrapper<LabItems> queryWrapperC = new QueryWrapper<>();
                    queryWrapperC.in("pid", idsB);
                    List<LabItems> itemsListC = labItemsService.list(queryWrapperC);
                    if (itemsListC != null) {
                        for (LabItems item : itemsListC) {
                            itemIds.add(item.getId());
                            devIds.add(item.getId());
                        }
                    }
                }
            }
        } else if (type.equals("B")) {
            List<String> idsA = new ArrayList<>();
            QueryWrapper<LabItems> queryWrapperA = new QueryWrapper<>();
            queryWrapperA.eq("pid", labItems.getId());
            List<LabItems> itemsListA = labItemsService.list(queryWrapperA);
            if (itemsListA != null) {
                for (LabItems item : itemsListA) {
                    idsA.add(item.getId());
                    itemIds.add(item.getId());
                }
            }
            if (idsA.size() > 0) {
                QueryWrapper<LabItems> queryWrapperB = new QueryWrapper<>();
                queryWrapperB.in("pid", idsA);
                List<LabItems> itemsListB = labItemsService.list(queryWrapperB);
                if (itemsListB != null) {
                    for (LabItems item : itemsListB) {
                        itemIds.add(item.getId());
                        devIds.add(item.getId());
                    }
                }
            }
        } else if (type.equals("C")) {
            QueryWrapper<LabItems> queryWrapperA = new QueryWrapper<>();
            queryWrapperA.eq("pid", labItems.getId());
            List<LabItems> itemsListA = labItemsService.list(queryWrapperA);
            if (itemsListA != null) {
                for (LabItems item : itemsListA) {
                    itemIds.add(item.getId());
                    devIds.add(item.getId());
                }
            }
        }
        itemIds.add(id);
        // todo 删除lab_items
        labItemsService.removeBatchByIds(itemIds);
        // todo 删除lab_itmes_device
        if (devIds.size() > 0) {
            QueryWrapper<LabItemsDevice> wrapperb = new QueryWrapper<>();
            wrapperb.in("item_id", devIds.toArray());
            labItemsDeviceService.remove(wrapperb);
        }

        if (MyEnum.sync) {
            long time = new Date().getTime();
            String[] stringArray = itemIds.toArray(new String[0]);
            for (String str : stringArray) {
                System.out.println(str);
            }
            labCronJobService.saveCronBatch("lab_items", "2", time,  itemIds.toArray(new String[0]));
            if(devIds.size() > 0){
                labCronJobService.saveCronBatch("lab_items_device", "2", time,  devIds.toArray(new String[0]));
            }
        }

        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "实验项目信息表-批量删除")
    @ApiOperation(value = "实验项目信息表-批量删除", notes = "实验项目信息表-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        String[] split = ids.split(",");
        labItemsService.removeByIds(Arrays.asList(split));

        QueryWrapper<LabItemsDevice> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("item_id", split);
        labItemsDeviceService.remove(queryWrapper);

        if (MyEnum.sync) {
            long time = new Date().getTime();
            labCronJobService.saveCronBatch("lab_items", "2", time, split);
            labCronJobService.saveCronBatchA("lab_items_device", "2", time, split);
        }
        return Result.OK("批量删除成功!");
    }

    /**
     * 收藏
     *
     * @param id
     * @return
     */
    @AutoLog(value = "实验项目信息表-收藏")
    @ApiOperation(value = "实验项目信息表-收藏", notes = "实验项目信息表-收藏")
    @RequestMapping(value = "/collect", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> collect(@RequestParam(name = "id", required = true) String id,
                                  @RequestParam(name = "collect", required = true) String collect) {
        QueryWrapper<LabItems> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        LabItems labItems = labItemsService.getById(id);
        labItems.setCollect(collect);
        labItemsService.updateById(labItems);

        if (MyEnum.sync) {
            long time = new Date().getTime();
            LabCronJob job = new LabCronJob("lab_items", "1", time, 1);
            labCronJobService.save(job);
        }
        return Result.OK("收藏成功!");
    }


    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "实验项目信息表-通过id查询", notes = "实验项目信息表-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<LabItems> queryById(@RequestParam(name = "id", required = true) String id) {
        LabItems labItems = labItemsService.getById(id);
        if (labItems == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(labItems);
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "实验项目信息表-通过id查询", notes = "实验项目信息表-通过id查询")
    @GetMapping(value = "/queryItemsById")
    public Result<LabItemsDeviceVo> queryItemsById(@RequestParam(name = "id", defaultValue = "") String id) {
        LabItems labItems = labItemsService.getById(id);
        if (labItems == null) {
            return Result.error("未找到对应数据");
        }
        LabItemsDeviceVo itemsDeviceVo = new LabItemsDeviceVo();
        BeanUtils.copyProperties(labItems, itemsDeviceVo);
        QueryWrapper<LabItemsDevice> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("item_id", labItems.getId());
        itemsDeviceVo.setItemsDeviceList(labItemsDeviceService.list(queryWrapper));

        return Result.OK(itemsDeviceVo);
    }

    /**
     * 分页列表查询
     *
     * @return
     */
    @ApiOperation(value = "实验项目信息表-分页列表查询", notes = "实验项目信息表-分页列表查询")
    @GetMapping(value = "/typeList")
    public Result<IPage<LabItems>> queryTypeList() {
        QueryWrapper<LabItems> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("type", "C");
        Page<LabItems> page = new Page<LabItems>(1, 100);
        IPage<LabItems> pageList = labItemsService.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param labItems
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, LabItems labItems) {
        return super.exportXls(request, labItems, LabItems.class, "实验项目信息表");
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, LabItems.class);
    }

}
